-
Notifications
You must be signed in to change notification settings - Fork 8.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add rbeesley's ansi-color.cmd, a CMD-based color tool (& more) #11932
Conversation
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
holy shit yeah it does. I've never seen a batch script anything like this before, but it's kinda incredible like that. You should probably throw your username at the top of this script in a cooment as the author, because you deserve the credit for whatever witchcraft this is. I'm cool accepting this as a tool to our repo, because it would be handy for debugging purposes, likely moreso than |
.github/actions/spelling/expect/205c1ec487b80f127ca611d10b973f66d9ed6812.txt
Outdated
Show resolved
Hide resolved
team consensus:
|
Added a way to get the errorlevel from the CHCP call. If it fails, we can still use the result if there isn't a need for UTF-8. This should be more robust and should allow things to work even if CHCP isn't on a system for some reason. The consideration is that there might be a localization where this doesn't work so try to fail gracefuly. I also cleaned up the way help and internal errors are handled better now. Requesting help doesn't set an error level for internal commands, so this app won't either. Finally, addressed the speling errers I had in the first checkin. Forground (sic) is intentional because that is the spelling in the original BASH script. Other errors raised I corrected. I've tried to leave comments throughout, but if there is anything not understood, I can try to document it more.
@check-spelling-bot ReportUnrecognized words, please review:
Previously acknowledged words that are now absentRelayoutTo accept these unrecognized words as correct (and remove the previously acknowledged and now absent words), run the following commands... in a clone of the [email protected]:rbeesley/terminal.git repository
✏️ Contributor please read thisBy default the command suggestion will generate a file named based on your commit. That's generally ok as long as you add the file to your commit. Someone can reorganize it later.
If the listed items are:
See the 🔬 You can test your commits without appending to a PR by creating a new branch with that extra change and pushing it to your fork. The check-spelling action will run in response to your push -- it doesn't require an open pull request. By using such a branch, you can limit the number of typos your peers see you make. 😉 🗜️ If you see a bunch of garbageIf it relates to a ... well-formed patternSee if there's a pattern that would match it. If not, try writing one and adding it to a Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines. Note that patterns can't match multiline strings. binary-ish stringPlease add a file path to the File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.
|
It may read like Perl at times, but it should be complete now. If there is something you think is unclear, I can try to add more documentation, but I think the comments in the script should answer most questions and I tried to make the flow very modular. The main thing to remember is that to define the macros they need to be defined early on, but I wanted to add the configuration and data segment at the top. Configuration allows someone to set the condition of a flag, so they don't have to be passed on the command-line... actually that was the way this script was originally written, and the argument parsing was added later. Defining the CELL here is just a way to define something which doesn't have to be in definition files, and it actually makes it possible to use different definition files where just changing this one place changes whatever else is ran. I'm not sure any of the definitions I included use this technique, but you can imagine other ways this could be extended. The built-in definition is what I usually ran to review changes from build to build and when authoring color schemes. The main script doesn't start until about 362 lines in, but even this is designed to be very readable. Until 490, it is just trying to set the correct default values and settings, including changing the codepage if necessary. Then it reads the data segment, validates that the configuration supports the requirements of the definition, specifically UTF-8, then it resolves how the divisions should be drawn between table headings, cells, stubs, etc. Lastly it builds the table to a buffer and writes the buffer to the screen. After that it restores the codepage if it changed and exists. With labels and comments, I think it shouldn't be too difficult to read, but I've also rewritten it several times as I've introduced new functionality. As mentioned, it is a tool and a great demonstration that Command Scripting can accomplish more than expected. |
If there is an IF which checks for a string in a definition file, it is now case insensitive and shouldn't cause problems. Updated error output when CHCP fails and only show a warning if Unicode isn't required. If Unicode is required, then show an additional error and exit. This has a negative that even if the shell is running on codepage 65001, it will block the execution of a definition file which requests UTF8 or the flag is set. The error in this case still makes sense as this happens when trying to read the active codepage and the utility will not know if this fails at this point in execution. I think this is the right balance.
If there is anything evaluated which can cause an error this should be caught now. Trimmed the data before it is further evaluated to make sure extra whitespace is dropped but you can't indent in the definition files. Trimming before checking segments would fix this, but introduces a performance hit.
I'm happy with the current state. I made a few more changes to improve CHCP error handling and how things downgrade if that fails. Since the initial PR, I've also cleaned up the reading of the Data Segment so that it is more forgiving of case inconsistencies. There is more which could be done, but it seems to introduce performance problems to handle things like indentation in the definition files. It would be a nice to have, but probably not at that cost. |
Adding #SPC# to a column definition will do the same as adding a #SPC# to a row, in that it will add visual separation. This is unlike #NUL# which just doesn't apply an associated escape sequence but still writes the test text to a cell. #SPC# writes spaces instead. Also updated a couple of definitions which benefit from this change. Fixed sgr-intensity.def so that is shows intensity from low to high, flipping 1; and 2; attributes.
Fixed a case where special tokens were interpreted as column width for the stub so now they are 0 width. This allows the labels to be inserted into the middle of the table without affecting the overall width. Added a new definition for showing attributes and a label definition to demonstrate how labels can be used. They follow the pattern used for ECHO so that #LBL#[.| ][TEXT] will output the same way ECHO does. #LBL# can also use CSI commands to format the label. #LBL# will automatically apply RESET at the end of a line to prevent inconsistency.
@check-spelling-bot ReportUnrecognized words, please review:
Previously acknowledged words that are now absentadaa coffgroup coffgrp datetime eae emplate GENPROFILE HHmm Hostx installationpath MMdd pgorepro pgort PGU RelayoutTo accept these unrecognized words as correct (and remove the previously acknowledged and now absent words), run the following commands... in a clone of the [email protected]:rbeesley/terminal.git repository
✏️ Contributor please read thisBy default the command suggestion will generate a file named based on your commit. That's generally ok as long as you add the file to your commit. Someone can reorganize it later.
If the listed items are:
See the 🔬 You can test your commits without appending to a PR by creating a new branch with that extra change and pushing it to your fork. The check-spelling action will run in response to your push -- it doesn't require an open pull request. By using such a branch, you can limit the number of typos your peers see you make. 😉 🗜️ If you see a bunch of garbageIf it relates to a ... well-formed patternSee if there's a pattern that would match it. If not, try writing one and adding it to a Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines. Note that patterns can't match multiline strings. binary-ish stringPlease add a file path to the File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.
|
Added: mdecreased mincreased Removed: adaa coffgroup coffgrp datetime eae emplate GENPROFILE HHmm Hostx installationpath MMdd pgorepro pgort PGU Relayout Moved additional words from previous checkins to appropriate files
Re:
I recently added an ANSI color codes pattern to https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-patterns:
You could probably do:
|
@jsoref, thanks for the feedback. I looked at the CSI pattern you suggested. I think it would actually need to be something like:
And it supports all the CSI sequences I could quickly scrounge up. The problem I have with making this a pattern is that this isn't exhaustive. I know that it is an incomplete set of what could be available, and I don't know the set that Windows Terminal supports. Something like The base minimum, following your example would be Too much? Not enough? Using a pattern would probably be better but I'm not sure how deep to take this. |
Sorry about the lost slash. Personally I think that something is better than nothing, and it's an invitation for someone to improve it later. As long as you don't lose anything because of false positives, I see a pattern as a strict improvement. Fwiw, Instead of using the fancy
|
@jsoref, nice. I didn't consider that the insensitivity could be applied in the non-capturing group, but of course it could.
That's more readable than the form where you break it up into one character of groups. Final answer. |
I should have clarified: the pattern matcher is Perl. The comment includes customizable content: Here's my current default (which was written long after the above): It looks like the (I'm very close to a new release, but still beating some bugs out.... |
Added a separator.def which can model using separator variables in a definition file. For the table code to be "complete" there would need to be a border and row separators, but it seems like that would have low value as it would just grow the height without additional benefit. Similarly, borders would grow the width and height by two with no real perceived gain.
@check-spelling-bot ReportUnrecognized words, please review:
Previously acknowledged words that are now absentpgorepro pgort PGUTo accept these unrecognized words as correct (and remove the previously acknowledged and now absent words), run the following commands... in a clone of the [email protected]:rbeesley/terminal.git repository
✏️ Contributor please read thisBy default the command suggestion will generate a file named based on your commit. That's generally ok as long as you add the file to your commit. Someone can reorganize it later.
If the listed items are:
See the 🔬 You can test your commits without appending to a PR by creating a new branch with that extra change and pushing it to your fork. The check-spelling action will run in response to your push -- it doesn't require an open pull request. By using such a branch, you can limit the number of typos your peers see you make. 😉 🗜️ If you see a bunch of garbageIf it relates to a ... well-formed patternSee if there's a pattern that would match it. If not, try writing one and adding it to a Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines. Note that patterns can't match multiline strings. binary-ish stringPlease add a file path to the File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.
|
and renamed SEPARATOR.COL_INTERSECT to SEPARATOR.CELL_INTERSECT to better describe its use. Added a fgbg.def which gives a dense compact view of all FG and BG colors.
@check-spelling-bot ReportUnrecognized words, please review:
Previously acknowledged words that are now absentpgorepro pgort PGUTo accept these unrecognized words as correct (and remove the previously acknowledged and now absent words), run the following commands... in a clone of the [email protected]:rbeesley/terminal.git repository
✏️ Contributor please read thisBy default the command suggestion will generate a file named based on your commit. That's generally ok as long as you add the file to your commit. Someone can reorganize it later.
If the listed items are:
See the 🔬 You can test your commits without appending to a PR by creating a new branch with that extra change and pushing it to your fork. The check-spelling action will run in response to your push -- it doesn't require an open pull request. By using such a branch, you can limit the number of typos your peers see you make. 😉 🗜️ If you see a bunch of garbageIf it relates to a ... well-formed patternSee if there's a pattern that would match it. If not, try writing one and adding it to a Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines. Note that patterns can't match multiline strings. binary-ish stringPlease add a file path to the File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ryan, this is a magnum opus and we're proud to have you contribute it to our humble repo. Thank you.
Hello @DHowett! Because this pull request has the p.s. you can customize the way I help with merging this pull request, such as holding this pull request until a specific person approves. Simply @mention me (
|
🎉 Handy links: |
Adds the Ansi-Color tool, completing #6470.
What started out as an experiment to see the support of ANSI support to
conhost, I wanted to write a Windows equivalent of Daniel Crisman's
BASH script on tldp.org. I didn't like how the BASH script hard coded
in whitespace and I thought Windows could do better. I applied
techniques to speed up the execution and tried to use the Command Script
batch language in ways that pushed the limits for what I thought it
could do. Running this from withing PowerShell,
&cmd /c ansi-color.cmd
,I found out that the active code page is already 65001, but when ran
from a Command Prompt, the active code page depends on the regional
settings and I would have a dependency on CHCP to detect the active code
page, change to 65001 if necessary, and restore the previous code page
after running. I found it useful for designing color schemes and writing
shaders, and I started using an earlier version for logging bugs.
Initially it was a single script which I would dump every SGR
combination I could think of, and many which weren't implemented yet,
but as I was looking at other tools which had been written I wanted to
mimic the same output so I could do side-by-side comparisons. First I
wrote
crisman.def
and thencolortool.def
. So I had to align text.Then output was slow for big tables so I wrote to an outbuffer and made
use of macros. I wanted to handle flags instead of needing to change
settings every time, so I added argument parsing and loading external
files.
It's a batch file that has some really useful purposes and does nothing
I've seen before.
I've ran every definition in a Command Prompt, with CP 437 and CP 65001
to make sure it works. Posted as a Gist on my account for about year, a
Portuguese (Brazilian as I recall), speaking user tried the Gist and it
was failing because CHCP is localized. I've taken an approach to try and
make it work for different localizations, but this is a potential
problem. I also ran every definition in PowerShell 7, shelling down to
cmd
to actually run it. Lastly, I went through using the flags andmade sure that help would be shown. Error messages generate error levels
when the script exits, so those could be used to use this in an
automated test and catch if there was a problem with the script
executing. It won't be able to validate if the generated output shows
correctly, but it would fail if a definition file is missing or if it
needed to switch to Unicode and wasn't flagged or configured to do so.
For trying to build the table stub and headers, there is some debug code
which will output what was parsed. This is the last debug code in the
script itself, but I found it to be useful at times, so there is a
configuration setting which can turn that debug output back on.
Technically there is also a debug statement to break after adding the
macros and parsing the arguments, but before it does any configuration
changes, changes the code page, or anything. This was useful for making
changes to macros and being able to test them as well as making sure
that flags and arguments are parsed correctly. It was a rather cryptic
discovery to call
cmd /c exit -1073741510
to break out, so in partthat was my reason to leave this in. The definition files themselves
could be cleaned up further, but in both of them there are a lot of
Unicode codepoints that could be useful when defining division lines for
the headers so I opted to just comment them out. I initially had the
default definition to require Unicode, but now it just changes to a
non-Unicode output if it can't. And this brings up the last concern. The
way certain settings are set, is that they are defined in the
__TABLE__
section of the definition file. WithPARSE_TABLE_DATA
,the script looks line by line for
SET *
orIF *
and if found it willeffectively eval that line. The definition files are written so that for
instance
SET "CELL= gYw "
could be used to set the code which is used.If
was allow so that there could be a test if Unicode were availableand set something different for ASCII and Unicode. But it also opens the
possibility that a rogue actor could create a
ansi-color.cmd
definition file something like
SET "foo=bar" & DoSomethingBad.exe
.First of all I'd be flattered that anyone would use this very niche
tool, but it is something I think which needs to be called out.
Essentially the definition files are just batch files, but they are
extremely limited to executing only one line at a time and only
supporting IF and SET commands. I think this is a minimal risk because
at that point batch files would already be more effective, but there
should also be an expectation that a batch file will run something and
the same may not be true for the heavily degraded definition files. I
think the risk is minimal but it is a risk I wanted to make clear. This
really showcases some interesting techniques and ideas, and I hope that
it is useful. All told, there are a couple years of incremental changes
in this PR.
Closes #6470